﻿#include "dynamicmetacreator.h"

DynamicMetaCreator::DynamicMetaCreator(int size,std::function<void(void*)> destructor, const char *className, const MetaInfo &Super, std::function<Reflectable*(void*)> caster):DynamicMetaCreator(size,destructor,className)
{
	super = Super.GetBackend();
}

DynamicMetaCreator::DynamicMetaCreator(int size,std::function<void(void*)> destructor, const char *className, std::function<Reflectable*(void*)> caster)
{
	super = NULL;
	result.className = className;
	result.Size = size;
	result.Destory = destructor;
	result.Caster = caster;
}

void DynamicMetaCreator::addDefaultConstructor(std::function<void (void *)> fun)
{
	__StandardMetaInfoHelper::ConstructorInfo info;

	info.ArgTyps = {};
	info.con = [=](void* buffer, const void**param) {
		fun(buffer);
	};

	result.m_ConstructorInfo.push_back(info);
}

void DynamicMetaCreator::addCopyConstructor(std::function<void (void *,const void *)> fun)
{
	__StandardMetaInfoHelper::ConstructorInfo info;

	info.ArgTyps = {};
	info.con = [=](void* buffer,const void**param) {
		fun(buffer, param[0]);
	};

	result.m_ConstructorInfo.push_back(info);
}

DynamicMetaCreator::PropertyHelper::PropertyHelper(__StandardMetaInfoHelper::ClassData *meta, const char *name, MetaTypeId type)
{
    info = {};
	info.Name = name;
	info.Type = type;
    this->meta = meta;
}

DynamicMetaCreator::PropertyHelper DynamicMetaCreator::addProperty(const char *name, MetaTypeId type)
{
    PropertyHelper ret(&result,name,type);
    return ret;
}

DynamicMetaCreator::FunctionHelper DynamicMetaCreator::addFunction(const char *name,MetaTypeId ReturnType,const std::vector<MetaTypeId>& argTypes)
{
    FunctionHelper ret(&result,name,ReturnType,argTypes);
    return ret;
}

DynamicMetaCreator::SignalHelper DynamicMetaCreator::addSignal(const char *name, const std::vector<MetaTypeId> &argTypes)
{
    SignalHelper ret(&result,name,argTypes);
    return ret;
}

void DynamicMetaCreator::addClassInfo(const char *content)
{
	result.ClassInfo.push_back(content);
}

MetaInfo DynamicMetaCreator::finish()
{
	IMetaInfoBackend* backEnd = __StandardMetaInfoHelper::CreateMetaInfo(super, result);
	std::shared_ptr<IMetaInfoBackend> i(backEnd);
	return MetaInfo(backEnd);
}

DynamicMetaCreator::PropertyHelper &DynamicMetaCreator::PropertyHelper::addGetter( const FunctionAny& getter)
{
    info.getter = getter;
    return *this;
}

DynamicMetaCreator::PropertyHelper &DynamicMetaCreator::PropertyHelper::addSetter(const FunctionAny& setter)
{
	info.setter = setter;
    return *this;
}

DynamicMetaCreator::PropertyHelper &DynamicMetaCreator::PropertyHelper::addNotifier(const char *name)
{
	info.Notifier = name;
    return *this;
}

DynamicMetaCreator::PropertyHelper &DynamicMetaCreator::PropertyHelper::addInfo(const char *m)
{
	info.Infos.push_back(m);
    return *this;
}

void DynamicMetaCreator::PropertyHelper::finish()
{
	meta->m_PropertyInfos.push_back(info);
}

DynamicMetaCreator::FunctionHelper::FunctionHelper(__StandardMetaInfoHelper::ClassData *meta, const char *name, MetaTypeId ReturnType, const std::vector<MetaTypeId> &argTypes)
{
    info = {};
	info.Name = name;
	info.ArgTyps = argTypes;
	info.ReturnType = ReturnType;
    this->meta = meta;
}

DynamicMetaCreator::FunctionHelper &DynamicMetaCreator::FunctionHelper::setFunction(FunctionAny fun)
{
    info.fun = fun;

    return *this;
}

DynamicMetaCreator::FunctionHelper &DynamicMetaCreator::FunctionHelper::addInfo(const char *m)
{
    info.Infos.push_back(m);

    return *this;
}

void DynamicMetaCreator::FunctionHelper::finish()
{
	meta->m_FunctionInfo.push_back(info);
}

DynamicMetaCreator::SignalHelper::SignalHelper(__StandardMetaInfoHelper::ClassData *meta, const char *name, const std::vector<MetaTypeId> &argTypes)
{
    info = {};
	info.Name = name;
	info.ArgTypes = argTypes;

    this->meta = meta;
}

DynamicMetaCreator::SignalHelper &DynamicMetaCreator::SignalHelper::setSignal(std::function<GenericSignal *(void *)> fun)
{
	info.getter = fun;
    return *this;
}

DynamicMetaCreator::SignalHelper &DynamicMetaCreator::SignalHelper::addInfo(const char *e)
{
	info.Infos.push_back(e);
    return *this;
}

void DynamicMetaCreator::SignalHelper::finish()
{
	meta->m_SignalInfos.push_back(info);
}
